package com.zengfa.task.server.dao.jdbc;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.jdbc.core.simple.JdbcClient.StatementSpec;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.zengfa.task.api.enums.JobStatus;
import com.zengfa.task.server.dao.JobDao;
import com.zengfa.task.server.domain.entity.Job;

@Repository
@ConditionalOnBean(JdbcClient.class)
public class JobDaoJdbcImpl implements JobDao {

	@Autowired
	private JdbcClient jdbcClient;
	
	@Override
	public Job findJob(String jobGroup, String bizId) {
		String sql = "select * from job where job_group=? and biz_id=?";
		List<Job> list = jdbcClient.sql(sql).param(jobGroup).param(bizId).query(Job.class).list();
//		List<Job> list = jdbcTemplate.queryForList(sql,Job.class,jobGroup,bizId);
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}

	@Override
	public void save(Job job) {
		String sql = "insert into job(job_id,job_name,job_type,job_group,biz_id,exec_ip,start_time,"
				+ "end_time,status,insert_time,update_time,insert_by,update_by) values(:jobId,:jobName,:jobType,:jobGroup,:bizId,:execIp,:startTime,"
				+ ":endTime,:status,:insertTime,:updateTime,:insertBy,:updateBy)";
		int i = jdbcClient.sql(sql)
			.param("jobId",job.getJobId())
			.param("jobName",job.getJobName())
			.param("jobType",job.getJobType())
			.param("jobGroup",job.getJobGroup())
			.param("bizId",job.getBizId())
			.param("execIp",job.getExecIp())
			.param("startTime",job.getStartTime())
			.param("endTime",job.getEndTime())
			.param("status",job.getStatus().name())
			.param("insertTime",job.getInsertTime())
			.param("updateTime",job.getUpdateTime())
			.param("insertBy",job.getInsertBy())
			.param("updateBy",job.getUpdateBy())
			.update();
		if (i < 1) {
			throw new RuntimeException("保存任务失败");
		}
	}

	@Override
	public Job getById(String jobId) {
		String sql = "select * from job where job_id=? ";
		return jdbcClient.sql(sql).param(jobId).query(Job.class).single();
	}

	@Override
	public void updateById(Job job) {
		String sql = "update job set job_name=:jobName,job_type=:jobType,job_group=:jobGroup,biz_id=:bizId,message=:message,"
				+ "exec_ip=:execIp,start_time=:startTime,end_time=:endTime,status=:status,update_time=:updateTime,update_by=:updateBy  "
				+ "where job_id=:jobId";
		int i = jdbcClient.sql(sql)
			.param("jobId",job.getJobId())
			.param("jobName",job.getJobName())
			.param("jobType",job.getJobType())
			.param("jobGroup",job.getJobGroup())
			.param("bizId",job.getBizId())
			.param("execIp",job.getExecIp())
			.param("startTime",job.getStartTime())
			.param("endTime",job.getEndTime())
			.param("message",job.getMessage())
			.param("status",job.getStatus().name())
			.param("updateTime",job.getUpdateTime())
			.param("updateBy",job.getUpdateBy())
			.update();
	}

	@Override
	public List<Job> listByStatus(JobStatus status) {
		String sql = "select * from job where status=? order by insert_time";
		return jdbcClient.sql(sql).param(status.name()).query(Job.class).list();
	}

	@Override
	public boolean lock(String jobId) {
		String sql = "update job set optimistic=1 where job_id=? and optimistic is null";
		int i = jdbcClient.sql(sql).param(jobId).update();
		//等待1秒
		if (i < 1) {
			try {
				Thread.sleep(1000L);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			i = jdbcClient.sql(sql).param(jobId).update();
		}
		
		if (i == 1) {
			return true;
		}
		return false;
	}

	@Override
	public void unLock(String jobId) {
		String sql = "update job set optimistic=null where job_id=?";
		jdbcClient.sql(sql).param(jobId).update();
	}

	@Override
	public boolean updateByIdAndStatus(Job job, JobStatus beforeStatus) {
		StringBuffer sb = new StringBuffer();
		sb.append("update job set update_time=:updateTime,update_by=:updateBy");
		if (job.getStatus() != null) {
			sb.append(",status=:status");
		}
		if(StringUtils.hasText(job.getExecIp())) {
			sb.append(",exec_ip=:execIp");
		}
		if(StringUtils.hasText(job.getMessage())) {
			sb.append(",message=:message");
		}
		if(job.getStartTime() != null) {
			sb.append(",start_time=:startTime");
		}
		if(job.getEndTime() != null) {
			sb.append(",end_time=:endTime");
		}
		if(job.getLastSyncTime() != null) {
			sb.append(",last_sync_time=:lastSyncTime");
		}
		sb.append(" where job_id=:jobId and status=:beforeStatus");
		StatementSpec ss = jdbcClient.sql(sb.toString());
		ss.param("updateTime",job.getUpdateTime());
		ss.param("updateBy",job.getUpdateBy());
		ss.param("jobId",job.getJobId());
		ss.param("beforeStatus",beforeStatus.name());
		if (job.getStatus() != null) {
			ss.param("status",job.getStatus().name());
		}
		if(StringUtils.hasText(job.getExecIp())) {
			ss.param("execIp",job.getExecIp());
		}
		if(StringUtils.hasText(job.getMessage())) {
			ss.param("message",job.getMessage());
		}
		if(job.getStartTime() != null) {
			ss.param("startTime",job.getStartTime());
		}
		if(job.getEndTime() != null) {
			ss.param("endTime",job.getEndTime());
		}
		if(job.getLastSyncTime() != null) {
			ss.param("lastSyncTime",job.getLastSyncTime());
		}
		int i = ss.update();
		if(i > 0) {
        	return true;
        }
        return false;
	}

	@Override
	public void updSyncTime(Job job) {
		String sql = "update job set last_sync_time=:syncTime where job_id=:jobId";
		jdbcClient.sql(sql).param("syncTime",job.getLastSyncTime()).param("jobId",job.getJobId()).update();
	}

}
